#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDateTime>
#include <QRegularExpressionValidator>
#include <qcontainerfwd.h>
#include <qdebug.h>
#include <qhashfunctions.h>
#include <qlocale.h>
#include <qlogging.h>
#include <qnamespace.h>

MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
    ui->setupUi(this);
    initUI();
}

MainWindow::~MainWindow() {
    delete ui;
}
void MainWindow::initUI() {
    ui->txtSend->setPlainText(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz"));
    ui->checkBox->setStyleSheet("QCheckBox::indicator {width: 30px; height: 30px; }");
    ui->txtReceive->setReadOnly(true);
    ui->label_switch->setVisible(false);
    ui->label_switch->setText("0");

    QRegularExpression regExp("[1-9][0-9]*");   // 正则表达式匹配大于0的正整数
    QValidator* validator = new QRegularExpressionValidator(regExp, this);
    ui->txt_T->setValidator(validator);

    ui->checkBox->setCheckState(Qt::Unchecked);
    ui->checkBox->setEnabled(false);
    ui->txt_T->setEnabled(false);

    for (qint16 i = 3; i <= 5; i++) {   // 10个COM
        ui->cmb_portNum->addItem(QString("ttyS%1").arg(i));
    }
    ui->cmb_portNum->setCurrentIndex(2);

    // 波特率
    ui->cmb_baud->addItem(QString("1200"), QSerialPort::Baud1200);
    ui->cmb_baud->addItem(QString("2400"), QSerialPort::Baud2400);
    ui->cmb_baud->addItem(QString("4200"), QSerialPort::Baud4800);
    ui->cmb_baud->addItem(QString("9600"), QSerialPort::Baud9600);
    ui->cmb_baud->addItem(QString("19200"), QSerialPort::Baud19200);
    ui->cmb_baud->addItem(QString("38400"), QSerialPort::Baud38400);
    ui->cmb_baud->addItem(QString("57600"), QSerialPort::Baud57600);
    ui->cmb_baud->addItem(QString("115200"), QSerialPort::Baud115200);
    ui->cmb_baud->setCurrentIndex(7);

    // 数据位

    ui->cmb_data->addItem("8", QSerialPort::Data8);
    ui->cmb_data->addItem("7", QSerialPort::Data7);
    ui->cmb_data->addItem("6", QSerialPort::Data6);
    ui->cmb_data->addItem("5", QSerialPort::Data5);

    // 校验位
    ui->cmb_check->addItem("NONE", QSerialPort::NoParity);
    ui->cmb_check->addItem("ODD", QSerialPort::OddParity);
    ui->cmb_check->addItem("EVEN", QSerialPort::EvenParity);
    ui->cmb_check->addItem("MARK", QSerialPort::MarkParity);
    ui->cmb_check->addItem("SPACE", QSerialPort::SpaceParity);

    // 停止位
    ui->cmb_stop->addItem("1", QSerialPort::OneStop);
    ui->cmb_stop->addItem("1.5", QSerialPort::OneAndHalfStop);
    ui->cmb_stop->addItem("2", QSerialPort::TwoStop);

    // 流控制
    ui->cmb_flow->addItem("NONE", QSerialPort::NoFlowControl);
    ui->cmb_flow->addItem("RTS/CTS", QSerialPort::HardwareControl);
    ui->cmb_flow->addItem("XON/XOFF", QSerialPort::SoftwareControl);

    // 串口有数据
    connect(&sp, &QSerialPort::readyRead, this, &MainWindow::spReadData);

    // 看看写了多少字节数
    connect(&sp, &QSerialPort::bytesWritten, [=](qint64 bytes) {
        qDebug() << "发送的字节数为：" << QString::number(bytes);
    });

    connect(&timer, &QTimer::timeout, [&]() {
        qDebug() << "定时器触发。。。";
        sp.write(ui->txtSend->toPlainText().toUtf8());
    });
}
void MainWindow::on_btn_switch_clicked() {
    // 表示点击前串口处于关闭状态，点击打开
    if (ui->label_switch->text() == "0") {
        sp.setPortName(ui->cmb_portNum->currentText());
        qDebug() << ui->cmb_portNum->currentText();
        sp.setBaudRate(ui->cmb_baud->currentData().toInt());
        sp.setParity((QSerialPort::Parity)ui->cmb_check->currentData().toInt());
        sp.setDataBits((QSerialPort::DataBits)ui->cmb_data->currentData().toInt());
        sp.setStopBits((QSerialPort::StopBits)ui->cmb_stop->currentData().toInt());
        sp.setFlowControl((QSerialPort::FlowControl)ui->cmb_flow->currentData().toInt());

        bool isOpen = sp.open(QIODevice::ReadWrite);   // 打开串口
        if (isOpen) {                                  // 打开成功
            ui->checkBox->setEnabled(true);
            ui->txt_T->setEnabled(true);
            ui->groupBox->setEnabled(false);   // groubox中所有控件不可用
            ui->label_switch->setText("1");
            ui->btn_switch->setStyleSheet("QPushButton { background-color: green;}");
        } else {   // 打开失败
            ui->statusBar->showMessage(sp.errorString(), 5000);
            qDebug() << "失败了：" << ui->cmb_portNum->currentText();
        }
    } else {   // 表示点击前串口处于打开状态，点击关闭
        sp.close();
        ui->checkBox->setEnabled(false);
        ui->checkBox->setCheckState(Qt::Unchecked);
        ui->txt_T->setEnabled(false);
        ui->txt_T->setDragEnabled(false);
        ui->groupBox->setEnabled(true);   // groubox中所有控件可用
        ui->label_switch->setText("0");
        ui->btn_switch->setStyleSheet("QPushButton { background-color: white;}");
    }
}

void MainWindow::spReadData() {   // 读取串口数据
    QByteArray byteData = sp.readAll();
    QString strData = QString(byteData);

    QString strTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz: ");
    ui->txtReceive->appendPlainText(strTime + strData + "\n");
}

// 看看写了多少字节的数据
void MainWindow::bytesWritten(qint64 bytes) {
    qDebug() << "发送的字节数为：" << QString::number(bytes);
}

void MainWindow::on_btn_send_clicked() {
    sp.write(ui->txtSend->toPlainText().toUtf8());   // 向串口写入数据
}

void MainWindow::on_checkBox_stateChanged(int i) {
    qDebug() << "复选框：" << i;
    if (i == 2) {   // 定时发送选中
        ui->txt_T->setEnabled(false);
        if (ui->txt_T->text().isEmpty()) {   // 如果延时框中是空，置1000
            ui->txt_T->setText("1000");
        }
        timer.start(ui->txt_T->text().toInt());
    }
    if (i == 0) {
        timer.stop();
        ui->txt_T->setEnabled(true);
    }
}

void MainWindow::on_ben_clean_send_clicked() {
    ui->txtSend->clear();
}
void MainWindow::on_ben_clean_rec_clicked() {
    ui->txtReceive->clear();
}
